package org.testis.orm.refinedclasses;

import org.orm.PersistentException;
import org.testis.orm.classes.T_dmap_objectpair;
import org.testis.orm.classes.T_dmap_objectpairCriteria;
import org.testis.orm.classes.T_dmap_objects;
import org.testis.orm.classes.T_dmap_params;
import org.testis.utils.middleware.DynamicMap;

/**
 * 
 * @author Cahit Emir Erel
 */
public class DynamicMapParameter {

    private T_dmap_params m_parameter = null;
    private T_dmap_objectpair m_reference = null;
    private T_dmap_objects m_parentObject = null;
    String run_time_value;

    /**
     * 
     * @param parameter
     * @param reference
     * @param object
     * @throws NullPointerException
     */
    public DynamicMapParameter(T_dmap_params parameter,
	    T_dmap_objectpair reference, T_dmap_objects object) {
	setReference(reference);
	setParentObject(object);
	setParameter(parameter);
	setRunTimeValue(null);
    }

    synchronized public DynamicMapParameter createRefinedDatabaseCopy(
	    T_dmap_objects object) throws PersistentException {
	T_dmap_objectpair newObjectPair = createDatabaseCopy(object);
	return new DynamicMapParameter(getParameter(), newObjectPair, object);
    }

    private T_dmap_objectpair createDatabaseCopy(T_dmap_objects object)
	    throws PersistentException {
	try {
	    T_dmap_objectpair newPair = new T_dmap_objectpair();
	    newPair.setObject(object);
	    newPair.setParam(getParameter());
	    newPair.setValue(getReference().getValue());
	    if (newPair.save()) {
		return newPair;
	    } else {
		throw new PersistentException();
	    }
	} catch (NullPointerException ex) {
	    ex.printStackTrace();
	    throw new PersistentException(
		    "This PostCondition Case has no reference or no ContainerType! Don't set reference to null or check ContainerType columns in database!");
	}
    }

    public boolean delete() throws PersistentException {
	try {
	    if (getName().equals("AbstractId")) {
		T_dmap_objectpairCriteria t_dmap_objectpairCriteria = new T_dmap_objectpairCriteria();
		t_dmap_objectpairCriteria.value.eq(getReference().getValue());
		T_dmap_objectpair[] pairs = t_dmap_objectpairCriteria
			.listT_dmap_objectpair();
		if (pairs != null && pairs.length == 1) {
		    DynamicMap.newInstance().deleteAbstractObject(
			    getReference().getValue());
		}
	    }
	    if (getReference().deleteAndDissociate()) {
		return true;
	    }
	} catch (NullPointerException ex) {
	    return true;
	}
	return false;
    }

    public Integer getId() {
	return getParameter().getId();
    }

    public String getName() {
	return getParameter().getName();
    }

    @Override
    public String toString() {
	try {
	    StringBuffer buffer = new StringBuffer();
	    buffer.append("(Parameter Id:" + this.getId() + ")");
	    buffer.append("Parameter[" + this.getParameter().getRank());
	    buffer.append("]:" + this.getName() + "=");
	    if (this.getReference() != null) {
		buffer.append(this.getReference().getValue());
	    }
	    return buffer.toString();
	} catch (NullPointerException ex) {
	    ex.printStackTrace();
	    return null;
	}
    }

    /**
     * Sets the objectpair reference of the DynamicMap parameter
     * 
     * @param enclosedObjectPair
     * @throws NullPointerException
     */
    private void setReference(T_dmap_objectpair enclosedObjectPair) {
	if (enclosedObjectPair == null) {
	    throw new NullPointerException();
	}
	m_reference = enclosedObjectPair;
    }

    public T_dmap_objectpair getReference() {
	return m_reference;
    }

    /**
     * 
     * @param parentObject
     * @throws NullPointerException
     */
    private void setParentObject(T_dmap_objects parentObject) {
	if (parentObject == null) {
	    throw new NullPointerException();
	}
	m_parentObject = parentObject;
    }

    public T_dmap_objects getParentObject() {
	return m_parentObject;
    }

    /**
     * 
     * @param parameter
     * @throws NullPointerException
     */
    private void setParameter(T_dmap_params parameter) {
	if (parameter == null) {
	    throw new NullPointerException();
	}
	m_parameter = parameter;
    }

    public T_dmap_params getParameter() {
	return m_parameter;
    }

    public void setRunTimeValue(String value) {
	this.run_time_value = value;
    }

    public String getRunTimeValue() {
	return this.run_time_value;
    }

    public String getValue() {
	if (getRunTimeValue() != null) {
	    return getRunTimeValue();
	}
	return this.getReference().getValue();
    }
}
